<?php
/**
 * Game_Building
 *
 * Класс Game_Building отвечает за обработку зданий
 *
 * @author Дмитрий Кузьма <kouzma.d@gmail.com>
 * @version 1.0
 */
class Game_Building extends ActiveRecord {
	
	protected static $_tableName = 'building';
	protected static $_pkName = 'ID_building';
	protected static $_arrAllBuildingsInfo;
	public $objResources;// Game_ResourceWithProduction;
  
	protected static $_arrBuildingsNames = array(
		1 => 'Ферма',	
		2 => 'Лесоруб',
		3 => 'Глиняный карьер',
		4 => 'Железный рудник',
		5 => 'Главное здание',
		6 => 'Амбар',
		7 => 'Склад',
		8 => 'Рынок',
		10 => 'Академия',
		11 => 'Казарма',
		12 => 'Конюшня',
		13 => 'Мастерская',
	);
	
		/**
	 * Конструктор объекта (создание, инициализация, загрузка данных) 
	 * 
	 * @param mixed $arrInitialFields - ID объекта, либо массив с данными, либо строка что ищем
	 * @param array $arrSettings - Массив с настройками
	 */
	public function __construct($arrInitialFields = null, array $arrSettings = array()) {
		parent::__construct($arrInitialFields, $arrSettings);
		if (is_numeric($arrInitialFields) || isset($this->tableFields['resource_1'])) {
			$this->objResources = new Game_Resource($this->tableFields);
		}
	}
	
	/**
	 * Получает название ресурса по его идентификатору
	 * 
	 * @param int $resourceId
	 */
	public static function getBuildingName($buildingId) {
		return self::$_arrBuildingsNames[$buildingId];
	}
	
	/**
	 * Метод получает стоимость апгрейда здания до нужного уровня (с предыдущего)
	 * 
	 * @param int $level
	 * 
	 * @return Game_Resource
	 */
	public function getBuildingLevelUpgradeCost($level) {
		return $this->objResources->pow($this->getField('coeff'), $level - 1);
		// TODO - внедрить округления
	}
	
	/**
	 * Подсчитывает, сколько в базовом варианте требуется времени на строительство здания
	 * 
	 * @param float $buildingStartLevelTime
	 * @param float $buildingAdditionalLevelTime
	 * @param float $buildingTimeCoef
	 * @param int $level
	 * 
	 * @return int
	 */
	public static function getBuildingTime($buildingStartLevelTime, $buildingAdditionalLevelTime, $buildingTimeCoef, $level = 1) {
		$timeToBuild = $buildingStartLevelTime * pow($buildingTimeCoef, $level - 1) - $buildingAdditionalLevelTime;
		
		// Учитываем коэффициент скорости
		$objGeneral = Game_General::instance();
		$buildingSpeedCoef = $objGeneral->objPlace->getBuildingSpeed();
		$timeToBuild /= ($buildingSpeedCoef / 100);
		
		return round($timeToBuild, -1);
	}

	
	/**
	 * Возвращает описание здания на требуемом языке 
	 * 
	 * @return text
	 */
	public function getDescription() {
		return $this->getField('description_' . Service_Translate::getLang());
	}
	
	/**
	 * Проверяет, возможно ли построить данное здание когда-нибудь (т.е. когда будут существовать дополнительные)
	 *
	 * @param array $arrPlaceBuildings
	 * 
	 * @return bool - флаг, можно ли при таких зданиях в месте построить новое
	 */
	public function isAvailabbleToBuildInPlaceAnyTime(array &$arrPlaceBuildings) {
		foreach ($arrPlaceBuildings as $arrBuilding) {
			// Если такое здание уже было построено
			if ($this->id == $arrBuilding['ID_building']) {
				if (!$this->getField('is_multy')) return false; // Если не допускается множественная постройка подобных зданий
				else {
					if ($arrBuilding['level'] < $this->getField('max_level')) return false; // У предыдущего здания еще не достигнут максимальный уровень
				} 
			}
		}
		return true;
	}
	
	/**
	 * Проверяет, возможно ли построить данное здание
	 *
	 * @param array $arrPlaceBuildings
	 *
	 * @return array - массив необходимых и не построенных зданий
	 */
	public function getNecessaryBuildingsToBuildInPlace(array &$arrPlaceBuildings, array $arrNecessaryBuildings) {
		$arrNecessaryBildingsRet = array();
		foreach ($arrNecessaryBuildings as $arrNecessaryBuilding) {
			if ($arrNecessaryBuilding['ID_building'] != $this->id) continue;
			$isNeed = true;
			foreach ($arrPlaceBuildings as $arrBuilding) {
				// Если построено необходимое здание
				if ($arrBuilding['ID_building'] == $arrNecessaryBuilding['ID_building_need']) {
					// Если уровень здания достаточен
					if ($arrBuilding['level'] >= $arrNecessaryBuilding['level']) {
						$isNeed = false;
						break;
					}
				}
			}
			if ($isNeed) $arrNecessaryBildingsRet[] = $arrNecessaryBuilding;
		}
		return $arrNecessaryBildingsRet;
	}
	
	/**
	 * Возвращает все зависимости для необходимых зданий. Группирует их по ID конкретного здания
	 * 
	 * @param array $arrBuildingsIds
	 * @return array:
	 */
	public static function getBuildingsDependencesByIds(array $arrBuildingsIds) {
		if (!$arrBuildingsIds) return array();
		$objDb = Service_Database::instance();
		$stmt = "
			SELECT * 
			FROM `building_dependence`
			WHERE `ID_building` IN(" . Service_Escape::intEscapeJoin(',', $arrBuildingsIds) . ")
		";
		$arrDependences = $objDb->select($stmt);
		return $arrDependences;
	} 
	
	/**
	 * Получает список зданий по принципу синглтона
	 * 
	 * @return array
	 */
	public static function getAllBuildingsInfo() {
		self::_fillAllBuildingsInfo();
		return self::$_arrAllBuildingsInfo;
	}
	
	/**
	 * Заполняет информацию о зданиях
	 */
	private static function _fillAllBuildingsInfo() {
		if (empty(self::$_arrAllBuildingsInfo)) {
			$objDB = Service_Database::instance();
			$stmt = "SELECT *	FROM `building`";
			self::$_arrAllBuildingsInfo = Service_ArrayConverter::makeKeyArrayFromMultyArray($objDB->select($stmt), 'ID_building');
		}
	}
}
?>